package com.dingding.service.facade.common;

import java.math.BigDecimal;
import java.util.Date;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.dingding.common.core.beans.ChannelRefUser;
import com.dingding.common.core.beans.Organization;
import com.dingding.common.core.beans.RegisterChannel;
import com.dingding.common.core.beans.special.SpecialUserAuthInfo;
import com.dingding.common.core.beans.special.Specialuserinfo;
import com.dingding.common.core.beans.special.Specialuserlogin;
import com.dingding.common.core.beans.special.Specialuservehicleinfo;
import com.dingding.common.core.exception.bussiness.BizExpEnum;
import com.dingding.common.core.exception.bussiness.BussinessException;
import com.dingding.common.core.util.DateFormatUtil;
import com.dingding.common.core.util.ToolUtil;
import com.dingding.facade.commonservice.common.dto.city.ResOpenCityDTO;
import com.dingding.facade.commonservice.common.dto.company.ReqGetCompanyDTO;
import com.dingding.facade.commonservice.common.dto.company.ResGetCompanyListDTO;
import com.dingding.facade.commonservice.facade.city.ICityFacade;
import com.dingding.facade.commonservice.facade.company.ICompanyFacade;
import com.dingding.facade.user.common.constans.special.UserInfoConstant;
import com.dingding.facade.user.common.dto.common.ReqGetDriverAuthStatus;
import com.dingding.facade.user.common.dto.common.ReqRegisterDriverDTO;
import com.dingding.facade.user.common.dto.common.ResGetDriverAuthStatus;
import com.dingding.facade.user.common.enums.AuthType;
import com.dingding.facade.user.common.enums.UserSex;
import com.dingding.facade.user.dto.common.driver.ReqDriverAuthDTO;
import com.dingding.facade.user.dto.common.driver.ReqDriverUserDTO;
import com.dingding.facade.user.dto.common.driver.ReqSyncDriverAuthStateDTO;
import com.dingding.facade.user.dto.common.driver.ResDriverAuthDTO;
import com.dingding.facade.user.dto.common.driver.ResDriverAuthDetailsDTO;
import com.dingding.facade.user.dto.common.driver.ResSyncDriverAuthStateDTO;
import com.dingding.facade.user.facade.common.driver.IDriverFacade;
import com.dingding.service.core.common.dao.IDriverDao;
import com.dingding.service.core.common.service.IChannelRefUserService;
import com.dingding.service.core.common.service.IDriverService;
import com.dingding.service.core.common.service.IRegisterChannelService;
import com.dingding.service.core.special.dao.ISpeicalDriverDao;

/**
 * 
 * @ClassName: DriverFacadeImpl
 * @Description: 司机共同接口
 * @author hufan
 * @date 2016年12月1日 下午7:50:49
 *
 */
@Component("driverFacade")
public class DriverFacadeImpl implements IDriverFacade {

	Logger log = Logger.getLogger(DriverFacadeImpl.class);

	@Resource(name = "driverDao")
	private IDriverDao driverDao;

	@Resource(name = "speicalDriverDao")
	private ISpeicalDriverDao specialDriverDao;
	
	@Resource(name = "openFacade")
	private ICityFacade cityFacade;
	
	@Resource(name = "companyFacade")
	private ICompanyFacade companyFacade;
	
	@Resource(name = "driverService")
	private IDriverService driverService;
	
	@Resource(name = "channelRefUserService")
	private IChannelRefUserService channelRefUserService;
	
	@Resource(name = "registerChannelService")
	private IRegisterChannelService registerChannelService;
	
	/**
	 * 
	 * @Title: driverAuth 
	 * @Description: 司机认证的共同接口
	 * @param  reqDriverAuthDTO
	 * @throws BussinessException  参数说明 
	 * @return ResDriverAuthDTO    返回类型 
	 * @throws
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public ResDriverAuthDTO driverAuth(ReqDriverAuthDTO reqDriverAuthDTO) throws BussinessException {

		// 返回Dto
		ResDriverAuthDTO resDriverAuthDTO = new ResDriverAuthDTO();

		// 判断是初次提交申请，还是再次提交审核
		Specialuservehicleinfo specialuservehicleinfo = driverDao
				.getSpecialuservehicleinfoByUserId(reqDriverAuthDTO.getUserId());
		
		if (specialuservehicleinfo == null) {
			
			//判断是否是扫码注册
			RegisterChannel registerChannel = null;
			
			if(reqDriverAuthDTO.getChannelId() != null) {
				registerChannel = registerChannelService.queryRegisterChannelByChannelId(reqDriverAuthDTO.getChannelId());
				if(registerChannel == null) {
					log.error("registerChannel not exists.");
					throw new BussinessException(BizExpEnum.REGISTER_CHANNEL_IS_INVALID);
				}
				
				// 将来源渠道保存在driverRefChannel关联表中
				this.saveChannelRefUser(reqDriverAuthDTO.getUserId(),registerChannel.getChannelId(),reqDriverAuthDTO.getAuthType());
			}
			
			// 将车辆信息保存specialuservehicleinfo表中
			specialuservehicleinfo = this.saveSpecialUserVehicleInfo(reqDriverAuthDTO);

			// 将用户信息更新到司机用户表Specialuserinfo
			this.updateSpecialUserInfo(reqDriverAuthDTO);

			// 将身份信息保存到SpecialUserAuth表中
			this.saveSpecialUserAuthInfo(reqDriverAuthDTO,registerChannel);

		} else if (specialuservehicleinfo.getSuvStatus() == 3) {// 审核未通过的才可以再次提交审核
			
			// 更新用户车辆信息
			specialuservehicleinfo = this.updateSpecialUserVehicleInfo(reqDriverAuthDTO, specialuservehicleinfo);
			
			// 更新用户身份信息表
			this.updateSpecialUserInfo(reqDriverAuthDTO);
			
			//将身份信息保存到SpecialUserAuth表中
			this.updateSpecialUserAuthInfo(reqDriverAuthDTO);
			
		} else if(specialuservehicleinfo.getSuvStatus() == 1){
			
			throw new BussinessException(BizExpEnum.DRIVER_IS_WATING_DEAL);// 处于审核中
		} else if(specialuservehicleinfo.getSuvStatus() == 2) {
			
			throw new BussinessException(BizExpEnum.DRIVER_IS_PASSED);// 审核已通过，无需再次提交请求
		} else {
			
			throw new BussinessException(BizExpEnum.ILLEGAL_OPERATION);// 非法操作
		}
		
		// 修改司机登录表的角色
		driverDao.changeDriverRole(reqDriverAuthDTO.getUserId(), reqDriverAuthDTO.getAuthType());
		
		// 设置需要返回的信息
		resDriverAuthDTO.setSuvStatus(specialuservehicleinfo.getSuvStatus());

		return resDriverAuthDTO;
	}
	
	/**
	 * 
	 * @Title: getResDriverAuthDetails 
	 * @Description: 司机认证的信息详情
	 * @param  reqDriverUserDTO
	 * @throws BussinessException  参数说明 
	 * @return ResDriverAuthDetailsDTO    返回类型 
	 * @throws
	 */
	@Override
	public ResDriverAuthDetailsDTO getResDriverAuthDetails(ReqDriverUserDTO reqDriverUserDTO)
			throws BussinessException {

		ResDriverAuthDetailsDTO resDriverAuthDetailsDTO = new ResDriverAuthDetailsDTO();

		//从三张表查分别询司机基本信息、司机认证信息、司机车辆信息
		Specialuserinfo specialuserinfo = driverDao.getSpecialuserinfoByUserId(reqDriverUserDTO.getUserId());
		SpecialUserAuthInfo specialUserAuthInfo = driverDao.getSpecialUserAuthInfo(reqDriverUserDTO.getUserId());
		Specialuservehicleinfo specialuservehicleinfo = driverDao.getSpecialuservehicleinfoByUserId(reqDriverUserDTO.getUserId());
		
		if (specialUserAuthInfo == null || specialuservehicleinfo == null) {
			log.error("没有此用户！DriverFacadeImpl : getResDriverAuthDetails(). userId : " + reqDriverUserDTO.getUserId());
			throw new BussinessException(BizExpEnum.NO_THIS_USER);
		}
		
		//填充司机详情
		BeanUtils.copyProperties(specialuserinfo, resDriverAuthDetailsDTO,
				ToolUtil.getNullPropertyNames(specialuserinfo));
		BeanUtils.copyProperties(specialUserAuthInfo, resDriverAuthDetailsDTO,
				ToolUtil.getNullPropertyNames(specialUserAuthInfo));
		BeanUtils.copyProperties(specialuservehicleinfo, resDriverAuthDetailsDTO,
				ToolUtil.getNullPropertyNames(specialuservehicleinfo));
		
		//日期的处理
		resDriverAuthDetailsDTO.setJszLssueDate(DateFormatUtil.yyyy_MM_dd_HH(specialUserAuthInfo.getJszLssueDate()));// 初领驾驶证日期
		resDriverAuthDetailsDTO.setJszValidityPeriod(DateFormatUtil.yyyy_MM_dd_HH(specialUserAuthInfo.getJszValidityPeriod()));// 驾驶证有效期
		resDriverAuthDetailsDTO.setXszLssueDate(DateFormatUtil.yyyy_MM_dd_HH(specialuservehicleinfo.getXszLssueDate()));// 车辆注册日期
		
		//城市、所属公司处理
		ResOpenCityDTO resOpenCityDTO = cityFacade.getOpenCityByCityId(specialUserAuthInfo.getCityId());
		if(resOpenCityDTO != null) {
			resDriverAuthDetailsDTO.setCityName(resOpenCityDTO.getCityName());
		}
		ReqGetCompanyDTO reqGetCompanyDTO = new ReqGetCompanyDTO();
		reqGetCompanyDTO.setOrganizationId(specialUserAuthInfo.getOrganizationId());
		ResGetCompanyListDTO resGetCompanyListDTO = companyFacade.getCompanyDTO(reqGetCompanyDTO);
		if(resGetCompanyListDTO != null) {
			resDriverAuthDetailsDTO.setOrganizationName(resGetCompanyListDTO.getOrganizationName());
		}
		
		//图片路径
		resDriverAuthDetailsDTO.setIdCardOppositeImageUrl(ToolUtil.imageAddress(specialUserAuthInfo.getIdCardOppositeImage()));
		resDriverAuthDetailsDTO.setIdCardPositiveImageUrl(ToolUtil.imageAddress(specialUserAuthInfo.getIdCardPositiveImage()));
		resDriverAuthDetailsDTO.setJszCopyImageUrl(ToolUtil.imageAddress(specialUserAuthInfo.getJszCopyImage()));
		resDriverAuthDetailsDTO.setJszImageUrl(ToolUtil.imageAddress(specialUserAuthInfo.getJszImage()));
		resDriverAuthDetailsDTO.setVehicleImageUrl(ToolUtil.imageAddress(specialuservehicleinfo.getVehicleImage()));
		resDriverAuthDetailsDTO.setWorkLicenseImageUrl(ToolUtil.imageAddress(specialuservehicleinfo.getWorkLicenseImage()));
		resDriverAuthDetailsDTO.setXszCopyImageUrl(ToolUtil.imageAddress(specialuservehicleinfo.getXszCopyImage()));
		resDriverAuthDetailsDTO.setXszImageUrl(ToolUtil.imageAddress(specialuservehicleinfo.getXszImage()));
		resDriverAuthDetailsDTO.setUserAvatarUrl(ToolUtil.imageAddress(specialuserinfo.getUserAvatar()));
		
		return resDriverAuthDetailsDTO;
	}

	/**
	 * 
	 * @Title: saveSpecialuservehicleinfo
	 * @Description: 保存司机车辆信息 
	 * @param reqDriverAuthDTO 
	 * @return 参数说明 
	 * @return boolean 返回类型 
	 * @throws
	 */
	protected Specialuservehicleinfo saveSpecialUserVehicleInfo(ReqDriverAuthDTO reqDriverAuthDTO) {

		Specialuservehicleinfo specialuservehicleinfo = new Specialuservehicleinfo();

		BeanUtils.copyProperties(reqDriverAuthDTO, specialuservehicleinfo);

		specialuservehicleinfo.setUvId(UUID.randomUUID().toString());
		specialuservehicleinfo.setSuvStatus(1);// 设置处于审核中
		specialuservehicleinfo.setSubmitTime(new Date());// 提交时间
		specialuservehicleinfo.setIsAuth(1);
		specialuservehicleinfo.setThroughTime(new Date());

		//特殊处理：专车没有从业资格证、从业照片,出租车没有车辆颜色;设置默认值
		if(specialuservehicleinfo.getAuthType() == AuthType.TAXI.getCode()) {
			specialuservehicleinfo.setVehicleColor("");
		}
		if(specialuservehicleinfo.getAuthType() == AuthType.SPECIAL.getCode()) {
			specialuservehicleinfo.setWorkLicenseNumber("");
			specialuservehicleinfo.setWorkLicenseImage("");
		}
		
		//日期处理
		specialuservehicleinfo.setXszLssueDate(DateFormatUtil.yyyy_MM_dd(reqDriverAuthDTO.getXszLssueDate()));
		
		driverDao.saveSpecialuservehicleinfo(specialuservehicleinfo);

		return specialuservehicleinfo;
	}

	/**
	 * 
	 * @Title: updateSpecialUserVehicleInfo 
	 * @Description: 更新司机车辆信息表 
	 * @param reqDriverAuthDTO 
	 * @param specialuservehicleinfo 
	 * @return 参数说明 
	 * @return Specialuservehicleinfo
	 * 返回类型 @throws
	 */
	protected Specialuservehicleinfo updateSpecialUserVehicleInfo(ReqDriverAuthDTO reqDriverAuthDTO,
			Specialuservehicleinfo specialuservehicleinfo) {

		BeanUtils.copyProperties(reqDriverAuthDTO, specialuservehicleinfo,
				ToolUtil.getNullPropertyNames(reqDriverAuthDTO));

		//日期处理
		specialuservehicleinfo.setXszLssueDate(DateFormatUtil.yyyy_MM_dd(reqDriverAuthDTO.getXszLssueDate()));
		//将状态重新置为认证中
		specialuservehicleinfo.setSuvStatus(1);
		driverDao.updateSpecialuservehicleinfo(specialuservehicleinfo);

		return specialuservehicleinfo;
	}

	/**
	 * 
	 * @Title: updateSpecialuserinfo 
	 * @Description: TODO 
	 * @param reqDriverAuthDTO 
	 * @return 参数说明 
	 * @return boolean 返回类型 
	 * @throws
	 */
	protected void updateSpecialUserInfo(ReqDriverAuthDTO reqDriverAuthDTO) {

		Specialuserinfo specialuserinfo = driverDao.getSpecialuserinfoByUserId(reqDriverAuthDTO.getUserId());
		if (specialuserinfo == null) {
			
			//防止之前出现数据不同步的情况
			Specialuserlogin specialuserlogin = specialDriverDao.getSpecialUserLoginByUserId(reqDriverAuthDTO.getUserId());
			if(specialuserlogin == null) {
				log.error("没有此用户，不能认证！DriverFacadeImpl : updateSpecialUserInfo(). userId : " + reqDriverAuthDTO.getUserId());
				throw new BussinessException(BizExpEnum.NO_THIS_USER);
			}
			
			specialuserinfo = createSpecialuserinfo(reqDriverAuthDTO.getUserId(), specialuserlogin.getUserName());
			driverDao.saveSpecialuserinfo(specialuserinfo);
			
		}else {
			
			BeanUtils.copyProperties(reqDriverAuthDTO, specialuserinfo, ToolUtil.getNullPropertyNames(reqDriverAuthDTO));

			driverDao.updateSpecialuserinfo(specialuserinfo);
		}
	}

	/**
	 * 
	 * @Title: saveSpecialUserAuthInfo 
	 * @Description: 保存用户身份证信息
	 * @param reqDriverAuthDTO 参数说明 
	 * @return void 返回类型
	 *  @throws
	 */
	protected void saveSpecialUserAuthInfo(ReqDriverAuthDTO reqDriverAuthDTO,RegisterChannel registerChannel) {

		SpecialUserAuthInfo specialUserAuthInfo = new SpecialUserAuthInfo();
		BeanUtils.copyProperties(reqDriverAuthDTO, specialUserAuthInfo);

		//日期处理
		specialUserAuthInfo.setJszLssueDate(DateFormatUtil.yyyy_MM_dd(reqDriverAuthDTO.getJszLssueDate()));
		specialUserAuthInfo.setJszValidityPeriod(DateFormatUtil.yyyy_MM_dd(reqDriverAuthDTO.getJszValidityPeriod()));
		
		// 填充默认属性
		specialUserAuthInfo.setSpecialUserId(reqDriverAuthDTO.getUserId());
		specialUserAuthInfo.setSpecialAuthInfoId(UUID.randomUUID().toString());
		specialUserAuthInfo.setIs_del(1);
		specialUserAuthInfo.setAuthInfoStatus(2);

		//处理扫码注册自动挂到公司
		if(registerChannel != null) {
			Organization organization = companyFacade.getOrganizationById(registerChannel.getOrganizationId());
			
			if(organization == null) {
				log.error("registerChannel not exists.");
				throw new BussinessException(BizExpEnum.REGISTER_CHANNEL_IS_INVALID);
			}
			
			specialUserAuthInfo.setOrganizationId(organization.getOrganizationId());
			specialUserAuthInfo.setCityId(organization.getCityId());
		}
		
		driverDao.saveSpecialUserAuthInfo(specialUserAuthInfo);
	}

	/**
	 * 
	 * @Title: updateSpecialUserAuthInfo
	 * @Description: 
	 * @param reqDriverAuthDTO 参数说明 
	 * @return void 返回类型 
	 * @throws
	 */
	protected void updateSpecialUserAuthInfo(ReqDriverAuthDTO reqDriverAuthDTO) {

		SpecialUserAuthInfo specialUserAuthInfo = driverDao.getSpecialUserAuthInfo(reqDriverAuthDTO.getUserId());

		if (specialUserAuthInfo == null) {
			log.error("没有此用户，不能修改！DriverFacadeImpl : updateSpecialUserAuthInfo()");
			throw new BussinessException(BizExpEnum.NO_THIS_USER);
		}

		BeanUtils.copyProperties(reqDriverAuthDTO, specialUserAuthInfo,
				ToolUtil.getNullPropertyNames(reqDriverAuthDTO));

		//日期处理
		specialUserAuthInfo.setJszLssueDate(DateFormatUtil.yyyy_MM_dd(reqDriverAuthDTO.getJszLssueDate()));
		specialUserAuthInfo.setJszValidityPeriod(DateFormatUtil.yyyy_MM_dd(reqDriverAuthDTO.getJszValidityPeriod()));
		
		driverDao.updateSpecialUserAuthInfo(specialUserAuthInfo);

	}

	/**
	 * 
	 * 创建用户详细信息
	 * 
	 * @Title: createSpecialuserinfo 
	 * @param userId 用户ID 
	 * @param telPhone 手机号
	 * @author CHEHAUNBO
	 * @since V2.4.0
	 * 
	 */
	private Specialuserinfo createSpecialuserinfo(String userId, String telPhone) {

		Specialuserinfo specialuserinfo = new Specialuserinfo();
		specialuserinfo.setSuId(UUID.randomUUID().toString()); // 主键ID
		specialuserinfo.setUserId(userId); // 用户ID
		specialuserinfo.setNickName(UserInfoConstant.DEFAULT_USER_NICKNAME); // 用户昵称
		specialuserinfo.setAge(0); // 年龄
		specialuserinfo.setSex(UserSex.noset.getValue()); // 性别
		specialuserinfo.setUserTabloidAvatar(UserInfoConstant.DEFAULT_TABLOID_USERAVATAR); // 用户缩略头像
		specialuserinfo.setUserAvatar(UserInfoConstant.DEFAULT_USERAVATAR);// 用户头像
		specialuserinfo.setTelPhone(telPhone); // 手机号
		specialuserinfo.setUserLevel(new BigDecimal(5)); // 级

		return specialuserinfo;

	}
	/**
	 * 
	 * @Title: registerDriver 
	 * @Description: 注册司机(该版本支持出租车司机和专车司机的注册) 
	 * @param registerDriverDTO 注册司机所需参数
	 * @author YHQ 
	 * @since V2.5.7
	 * @return String 用户Id
	 * 
	 */
	@Override
	public String registerDriver(ReqRegisterDriverDTO registerDriverDTO) {
		
		return driverService.registerDriver(registerDriverDTO);
	}

	/**
	 * 
	 * @Title: getDriverAuthStatus 
	 * @Description: 获取司机认证状态
	 * @param reqGetDriverAuthStatus 客户端请求参数
	 * @author YHQ 
	 * @since V2.5.7
	 * @return ResGetDriverAuthStatus    返回类型
	 * 
	 */
	@Override
	public ResGetDriverAuthStatus getDriverAuthStatus(ReqGetDriverAuthStatus reqGetDriverAuthStatus) {
		
		return driverService.getDriverAuthStatus(reqGetDriverAuthStatus);
	}

	
	/**
	 * 
	 * @Title: getResSyncDriverAuthState 
	 * @Description: 获取车主认证状态
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	@Override
	public ResSyncDriverAuthStateDTO getResSyncDriverAuthState(ReqSyncDriverAuthStateDTO reqSyncDriverAuthStateDTO)
			throws BussinessException {
		//客户端请求bean非空判断
		if(reqSyncDriverAuthStateDTO==null || ToolUtil.isBlank(reqSyncDriverAuthStateDTO.getUserId())){
			return null;
		}
		
		return driverDao.getResSyncDriverAuthState(reqSyncDriverAuthStateDTO);
	}

	/**
	 * 
	 * @Title: saveDriverChannel 
	 * @Description: 将用户来源渠道保存
	 * @param  参数说明 
	 * @author hufan
	 * @return 返回类型 
	 * @throws
	 */
	public void saveChannelRefUser(String userId,Integer channelId,Integer registerType) {
		
		//判断该用户是否添加过来源
		ChannelRefUser refUser = channelRefUserService.queryChannelRefUserByUserId(userId);
		if(refUser != null) {
			log.error("refUser is exists.");
			return;
		}
		
		//查询该司机的手机号
		Specialuserinfo specialuserinfo = driverDao.getSpecialuserinfoByUserId(userId);
		
		ChannelRefUser channelRefUser = new ChannelRefUser();
		channelRefUser.setChannelId(channelId);
		channelRefUser.setCreateTime(new Date());
		channelRefUser.setUserId(userId);
		channelRefUser.setRegisterType(registerType);
		
		if(specialuserinfo != null) {
			channelRefUser.setUserTelPhone(specialuserinfo.getTelPhone());
		}else {
			channelRefUser.setUserTelPhone("N");
		}
		
		//不管成功与否，不能影响之后的司机认证信息的添加
		try {
			channelRefUserService.saveChannelRefUser(channelRefUser);
		} catch (Exception e) {
			log.error("添加用户来源失败.");
		}
	}
}
